package com.sddnytsh.body_buildingsystem.network

import com.sddnytsh.body_buildingsystem.data.model.ChatMessage
import com.sddnytsh.body_buildingsystem.data.model.Contact
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Response
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.sddnytsh.body_buildingsystem.config.NetworkConfig

class MessageApiService {
    private val client = OkHttpClient.Builder()
        .connectTimeout(5, java.util.concurrent.TimeUnit.SECONDS)
        .readTimeout(8, java.util.concurrent.TimeUnit.SECONDS)
        .writeTimeout(5, java.util.concurrent.TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .connectionPool(okhttp3.ConnectionPool(5, 5, java.util.concurrent.TimeUnit.MINUTES))
        .build()
    private val gson = Gson()

    /**
     * 获取联系人列表
     */
    suspend fun getContacts(userId: Long): Result<List<Contact>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/messages/contacts?userId=$userId")
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val jsonObject = gson.fromJson(responseBody, JsonObject::class.java)
                    
                    if (jsonObject.get("success").asBoolean) {
                        val contactsArray = jsonObject.getAsJsonArray("data")
                        val contacts = mutableListOf<Contact>()
                        
                        contactsArray.forEach { element ->
                            val contactJson = element.asJsonObject
                            val contact = Contact(
                                id = contactJson.get("id").asLong,
                                name = contactJson.get("name").asString,
                                avatar = contactJson.get("avatar").asString,
                                lastMessage = contactJson.get("lastMessage").asString,
                                lastMessageTime = contactJson.get("lastMessageTime").asString,
                                unreadCount = contactJson.get("unreadCount").asInt
                            )
                            contacts.add(contact)
                        }
                        
                        Result.success(contacts)
                    } else {
                        Result.failure(Exception(jsonObject.get("message").asString))
                    }
                } else {
                    Result.failure(Exception("HTTP ${response.code}: ${response.message}"))
                }
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    /**
     * 获取聊天消息
     */
    suspend fun getChatMessages(userId: Long, contactId: Long): Result<List<ChatMessage>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/messages/chat?userId=$userId&contactId=$contactId")
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val jsonObject = gson.fromJson(responseBody, JsonObject::class.java)
                    
                    if (jsonObject.get("success").asBoolean) {
                        val messagesArray = jsonObject.getAsJsonArray("data")
                        val messages = mutableListOf<ChatMessage>()
                        
                        messagesArray.forEach { element ->
                            val messageJson = element.asJsonObject
                            val message = ChatMessage(
                                id = messageJson.get("id").asLong,
                                senderId = messageJson.get("senderId").asLong,
                                receiverId = messageJson.get("receiverId").asLong,
                                content = messageJson.get("content").asString,
                                timestamp = messageJson.get("timestamp").asLong,
                                isRead = messageJson.get("isRead").asBoolean
                            )
                            messages.add(message)
                        }
                        
                        Result.success(messages)
                    } else {
                        Result.failure(Exception(jsonObject.get("message").asString))
                    }
                } else {
                    Result.failure(Exception("HTTP ${response.code}: ${response.message}"))
                }
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    /**
     * 发送消息
     */
    suspend fun sendMessage(senderId: Long, receiverId: Long, content: String): Result<ChatMessage> = withContext(Dispatchers.IO) {
        try {
            val requestBody = JsonObject().apply {
                addProperty("senderId", senderId)
                addProperty("receiverId", receiverId)
                addProperty("content", content)
            }

            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/messages/send")
                .post(requestBody.toString().toRequestBody("application/json".toMediaType()))
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val jsonObject = gson.fromJson(responseBody, JsonObject::class.java)
                    
                    if (jsonObject.get("success").asBoolean) {
                        val messageJson = jsonObject.getAsJsonObject("data")
                        val message = ChatMessage(
                            id = messageJson.get("id").asLong,
                            senderId = messageJson.get("senderId").asLong,
                            receiverId = messageJson.get("receiverId").asLong,
                            content = messageJson.get("content").asString,
                            timestamp = messageJson.get("timestamp").asLong,
                            isRead = messageJson.get("isRead").asBoolean
                        )
                        Result.success(message)
                    } else {
                        Result.failure(Exception(jsonObject.get("message").asString))
                    }
                } else {
                    Result.failure(Exception("HTTP ${response.code}: ${response.message}"))
                }
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    /**
     * 标记消息为已读
     */
    suspend fun markMessagesAsRead(userId: Long, contactId: Long): Result<Boolean> = withContext(Dispatchers.IO) {
        try {
            val requestBody = JsonObject().apply {
                addProperty("userId", userId)
                addProperty("contactId", contactId)
            }

            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/messages/mark-read")
                .post(requestBody.toString().toRequestBody("application/json".toMediaType()))
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val jsonObject = gson.fromJson(responseBody, JsonObject::class.java)
                    
                    if (jsonObject.get("success").asBoolean) {
                        Result.success(true)
                    } else {
                        Result.failure(Exception(jsonObject.get("message").asString))
                    }
                } else {
                    Result.failure(Exception("HTTP ${response.code}: ${response.message}"))
                }
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    /**
     * 搜索联系人
     */
    suspend fun searchContacts(userId: Long, keyword: String): Result<List<Contact>> = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("${NetworkConfig.BASE_URL}/api/messages/search-contacts?userId=$userId&keyword=$keyword")
                .build()

            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    val jsonObject = gson.fromJson(responseBody, JsonObject::class.java)
                    
                    if (jsonObject.get("success").asBoolean) {
                        val contactsArray = jsonObject.getAsJsonArray("data")
                        val contacts = mutableListOf<Contact>()
                        
                        contactsArray.forEach { element ->
                            val contactJson = element.asJsonObject
                            val contact = Contact(
                                id = contactJson.get("id").asLong,
                                name = contactJson.get("name").asString,
                                avatar = contactJson.get("avatar").asString,
                                lastMessage = contactJson.get("lastMessage").asString,
                                lastMessageTime = contactJson.get("lastMessageTime").asString,
                                unreadCount = contactJson.get("unreadCount").asInt
                            )
                            contacts.add(contact)
                        }
                        
                        Result.success(contacts)
                    } else {
                        Result.failure(Exception(jsonObject.get("message").asString))
                    }
                } else {
                    Result.failure(Exception("HTTP ${response.code}: ${response.message}"))
                }
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}
